[libcxx] Fix PR23589: std::function doesn't recognize null pointer to varargs function. Summary: This patch fixes __not_null's detection of nullptr by breaking it down into 4 cases. 1. `__not_null(Tp const&)`: Default case. Tp is not null. 2. `__not_null(Tp* __ptr);` Case for pointers to functions. 3. `__not_null(_Ret _Class::* __ptr);` Case for pointers to members. 4. `__not_null(function<Tp> const&);`: Cases for other std::functions. Reviewers: mclow.lists Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D11111 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@245335 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/functional b/include/functional index 6c57de0..3c9f5a7 100644 --- a/include/functional +++ b/include/functional
@@ -1327,6 +1327,22 @@ { }; +template <class _Fp> +_LIBCPP_INLINE_VISIBILITY +bool __not_null(_Fp const&) { return true; } + +template <class _Fp> +_LIBCPP_INLINE_VISIBILITY +bool __not_null(_Fp* __ptr) { return __ptr; } + +template <class _Ret, class _Class> +_LIBCPP_INLINE_VISIBILITY +bool __not_null(_Ret _Class::*__ptr) { return __ptr; } + +template <class _Fp> +_LIBCPP_INLINE_VISIBILITY +bool __not_null(function<_Fp> const& __f) { return !!__f; } + } // namespace __function #ifndef _LIBCPP_HAS_NO_VARIADICS @@ -1468,28 +1484,6 @@ typename aligned_storage<3*sizeof(void*)>::type __buf_; __base* __f_; - template <class _Fp> - _LIBCPP_INLINE_VISIBILITY - static bool __not_null(const _Fp&) {return true;} - template <class _R2, class ..._Ap> - _LIBCPP_INLINE_VISIBILITY - static bool __not_null(_R2 (*__p)(_Ap...)) {return __p;} - template <class _R2, class _Cp, class ..._Ap> - _LIBCPP_INLINE_VISIBILITY - static bool __not_null(_R2 (_Cp::*__p)(_Ap...)) {return __p;} - template <class _R2, class _Cp, class ..._Ap> - _LIBCPP_INLINE_VISIBILITY - static bool __not_null(_R2 (_Cp::*__p)(_Ap...) const) {return __p;} - template <class _R2, class _Cp, class ..._Ap> - _LIBCPP_INLINE_VISIBILITY - static bool __not_null(_R2 (_Cp::*__p)(_Ap...) volatile) {return __p;} - template <class _R2, class _Cp, class ..._Ap> - _LIBCPP_INLINE_VISIBILITY - static bool __not_null(_R2 (_Cp::*__p)(_Ap...) const volatile) {return __p;} - template <class _R2, class ..._Ap> - _LIBCPP_INLINE_VISIBILITY - static bool __not_null(const function<_R2(_Ap...)>& __p) {return !!__p;} - template <class _Fp, bool = !is_same<_Fp, function>::value && __invokable<_Fp&, _ArgTypes...>::value> struct __callable; @@ -1654,7 +1648,7 @@ >::type*) : __f_(0) { - if (__not_null(__f)) + if (__function::__not_null(__f)) { typedef __function::__func<_Fp, allocator<_Fp>, _Rp(_ArgTypes...)> _FF; if (sizeof(_FF) <= sizeof(__buf_) && is_nothrow_copy_constructible<_Fp>::value) @@ -1681,7 +1675,7 @@ : __f_(0) { typedef allocator_traits<_Alloc> __alloc_traits; - if (__not_null(__f)) + if (__function::__not_null(__f)) { typedef __function::__func<_Fp, _Alloc, _Rp(_ArgTypes...)> _FF; typedef typename __rebind_alloc_helper<__alloc_traits, _FF>::type _Ap;